import { Vector3 } from "./three.module.js";

//#region 求面法向 /08-光/Demo06-逐三角形作色.html
//获取三角面法线的方向
function getTrangleNormal(vertices, elements) {
    const normals = [];
    for (let i = 0; i < elements.length; i += 3) {

        let cur = elements[i] * 3;
        let node1 = new Vector3(vertices[cur], vertices[cur + 1], vertices[cur + 2]);

        cur = elements[i + 1] * 3;
        let node2 = new Vector3(vertices[cur], vertices[cur + 1], vertices[cur + 2]);

        cur = elements[i + 2] * 3;
        let node3 = new Vector3(vertices[cur], vertices[cur + 1], vertices[cur + 2]);


        let a = node2.clone().sub(node1);
        let b = node3.clone().sub(node2);
        let n = a.clone().cross(b).normalize();
        normals.push(...n, ...n, ...n);

    }
    return normals;
}

//获取三角面的顶点
function getTriangleVertices(vertices, elements) {
    const nodeArr = [];
    for (let i = 0; i < elements.length; i += 3) {
        let cur = elements[i] * 3;
        let node1 = new Vector3(vertices[cur], vertices[cur + 1], vertices[cur + 2]);

        cur = elements[i + 1] * 3;
        let node2 = new Vector3(vertices[cur], vertices[cur + 1], vertices[cur + 2]);

        cur = elements[i + 2] * 3;
        let node3 = new Vector3(vertices[cur], vertices[cur + 1], vertices[cur + 2]);

        nodeArr.push(...node1);
        nodeArr.push(...node2);
        nodeArr.push(...node3);
    }
    return nodeArr;
}
//#endregion

//#region 求顶点法向
function getVerticeNormals(vertices, elements, type = 1) {
    const noramls = [];
    for (let i = 0; i < vertices.length / 3; i++) {
        let verticeIndex = i;
        //获取与当前顶点相邻的三角形
        const triangles = _getAdyTriangle(verticeIndex, vertices, elements);
        const curnormal = new Vector3();
        if (type) {
            // 加权三角形
            const sumArea = (() => {
                let sum = 0;
                triangles.forEach(element => {
                    sum += element[1];
                });
                return sum;
            })();
            //加权的顶点法线就是相接三角面的法线(长度为当前面积占总面积的百分比)之和
            triangles.forEach(([normal, area]) => {
                curnormal.add(normal.setLength(area / sumArea));
            })
        } else {
            //不加权的顶点法线是相接三角面的法线之和
            triangles.forEach(([normal, area]) => {
                curnormal.add(normal.normalize())
            })
        }
        noramls.push(...curnormal.normalize());
    }
    return noramls;
}

//获取顶点相邻的三角形
function _getAdyTriangle(index, vertices, elements) {
    const trangle = [];
    for (let j = 0; j < elements.length; j += 3) {
        if (elements.slice(j, j + 3).includes(index)) {
            let node1 = _getVerticeOfIndex(elements[j], vertices);
            let node2 = _getVerticeOfIndex(elements[j + 1], vertices);
            let node3 = _getVerticeOfIndex(elements[j + 2], vertices);
            let normal = node2.clone().sub(node1).cross(node3.clone().sub(node2));
            let area = normal.length() / 2;
            trangle.push([normal, area]);
        }
    }

    return trangle;
}
//#endregion

function _getVerticeOfIndex(index, vertices) {
    return new Vector3(vertices[index * 3], vertices[index * 3 + 1], vertices[index * 3 + 2]);
}

export {
    getTrangleNormal, getTriangleVertices,
    getVerticeNormals,
}
